package com.osmino.contacts.list;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ContentUris;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.util.SparseBooleanArray;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import com.osmino.contacts.IntentsTable;
import com.osmino.contacts.R;
import com.osmino.contacts.entity.Contact;
import com.osmino.contacts.entity.Email;
import com.osmino.contacts.entity.Group;
import com.osmino.contacts.entity.Phone;
import com.osmino.contacts.help.HelpActivity;
import com.osmino.contacts.provider.ContactsContractQueries;
import com.osmino.contacts.provider.ContactsContractResolver;
import com.osmino.contacts.provider.SendMessageUtils;
import com.osmino.contacts.provider.ContactsContractResolver.ContactsDataObserver;
import com.osmino.contacts.search.SearchDublicatesActivity;
import com.osmino.contacts.settings.SettingsActivity;
import com.osmino.core.AbsListActivity;
import com.osmino.core.DialogGenerator;
import com.osmino.core.DialogInfo;
import com.osmino.core.utils.view.Backgroung;

public final class ContactViewActivity extends AbsListActivity implements ContactsDataObserver,
		IContactViewController, OnClickListener {

	private ContactsContractResolver mContactsContractResolver;
	private DialogGenerator mDialogGenerator;
	private ContactViewAdapter mAdapter;
	private Contact mContact;
	private static final int RINGTONE_REQUEST_CODE = 0;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		mContactsContractResolver = mHostApplication.getContactsContractResolver();
		mDialogGenerator = new DialogGenerator(this, this);
		setContentView(R.layout.contact_view);
		mAdapter = new ContactViewAdapter(this, this);
		setListAdapter(mAdapter);
		mContactsContractResolver.registerContactsDataObserver(this);
		if (!mContactsContractResolver.isContactListsReady()) {
			showDialog(R.id.dialog_waiting);
		} else {
			initContact();
		}
		prepTitle();
	}

	private void prepTitle() {
		findViewById(R.id.title_bar_add_icon).setVisibility(View.GONE);
		ImageView iv = (ImageView) findViewById(R.id.title_bar_edit_icon);
		Backgroung
				.setResource(iv, R.drawable.base_title_edit_ic_act, R.drawable.base_title_edit_ic);
		findViewById(R.id.title_bar_edit_icon).setOnClickListener(this);
		((TextView) findViewById(R.id.title_bar_text)).setText(R.string.contact_info);
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		mContactsContractResolver.unregisterContactsDataObserver(this);
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (requestCode == RINGTONE_REQUEST_CODE) {
			if (resultCode == RESULT_OK) {
				mContact.ringtone = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
				ContactsContractQueries.editContact(this, mContact, new ArrayList<Group>(),
						new ArrayList<Group>());
				mAdapter.notifyDataSetChanged();
			}
		}
	}

	@Override
	protected Dialog onCreateDialog(int id) {
		Dialog dialog = null;
		switch (id) {
			case R.id.dialog_waiting:
				dialog = mDialogGenerator.createWaitingDialog();
				break;
			case R.id.dialog_contact_groups_list:
				dialog = mDialogGenerator.createContactGroupsDialog();
				break;
			case R.id.dialog_merge_contacts:
				dialog = mDialogGenerator.createMergeContactsDialog();
				break;
			default:
				dialog = super.onCreateDialog(id);
		}
		return dialog;
	}

	@Override
	protected void onPrepareDialog(int id, Dialog dialog) {
		switch (id) {
			case R.id.dialog_contact_groups_list:
				mDialogGenerator.prepareContactGroupsDialog((AlertDialog) dialog,
						mContactsContractResolver.getListGroups(), mContact.getGroupIds());
				break;
			case R.id.dialog_merge_contacts:
				mDialogGenerator.prepareMergeContactsDialog((AlertDialog) dialog, mContact,
						mContactsContractResolver.getListContacts());
				break;
			default:
				super.onPrepareDialog(id, dialog);
		}
	}

	@Override
	public void onDialogCallback(DialogInfo dialogCallbackInfo) {
		int dialogId = dialogCallbackInfo.dialogId;
		if (dialogId == R.id.dialog_merge_contacts) {
			onMergeDialogCallback(dialogCallbackInfo);
		} else if (dialogId == R.id.dialog_contact_groups_list) {
			onContactGroupsDialogCallback(dialogCallbackInfo);
		}
	}

	private void onMergeDialogCallback(DialogInfo dialogCallbackInfo) {
		if (dialogCallbackInfo.whichButton == Dialog.BUTTON_POSITIVE) {
			ListView listView = dialogCallbackInfo.listView;
			SparseBooleanArray checkedItems = listView.getCheckedItemPositions();
			List<Contact> resultList = new ArrayList<Contact>();
			int size = listView.getCount();
			for (int i = 0; i < size; i++) {
				if (checkedItems.get(i)) {
					resultList.add((Contact) listView.getAdapter().getItem(i));
				}
			}
			ContactsContractQueries.mergeContacts(this, mContact, resultList);
		}
	}

	private void onContactGroupsDialogCallback(DialogInfo dialogCallbackInfo) {
		if (dialogCallbackInfo.whichButton == Dialog.BUTTON_POSITIVE) {
			ListView listView = dialogCallbackInfo.listView;
			SparseBooleanArray checkedItems = listView.getCheckedItemPositions();
			List<Group> addedGroups = new ArrayList<Group>();
			List<Group> deletedGroups = new ArrayList<Group>();
			List<Long> groupIds = mContact.getGroupIds();
			int size = listView.getCount();
			for (int i = 0; i < size; i++) {
				Group group = (Group) listView.getAdapter().getItem(i);
				Long groupId = listView.getAdapter().getItemId(i);
				boolean contactInGroup = groupIds.contains(groupId);
				boolean checked = checkedItems.get(i);
				if (contactInGroup && !checked) {
					deletedGroups.add(group);
				} else if (!contactInGroup && checked) {
					addedGroups.add(group);
				}
			}
			ContactsContractQueries.editContact(this, mContact, addedGroups, deletedGroups);
		}
	}

	@Override
	public void onBackPressed() {
		Intent activityCall = new Intent(Intent.ACTION_VIEW);
		activityCall.setData(ContactsContract.Contacts.CONTENT_URI);
		activityCall.setPackage(getPackageName());
		startActivity(activityCall);
	}

	@Override
	protected void onListItemClick(ListView listView, View view, int position, long id) {
		int viewType = mAdapter.getItemViewType(position);
		switch (viewType) {
			case ContactViewAdapter.GROUP_ITEM_TYPE:
				showDialog(R.id.dialog_contact_groups_list);
				break;
			case ContactViewAdapter.RINGTONE_ITEM_TYPE:
				startRingtonePicker();
				break;
		}
	}

	private void startRingtonePicker() {
		Intent activityCall = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
		activityCall.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, mContact.ringtone);
		activityCall.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_RINGTONE);
		activityCall.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true);
		activityCall.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, true);
		startActivityForResult(activityCall, RINGTONE_REQUEST_CODE);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.contacts_option_menu, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		int itemId = item.getItemId();
		switch (itemId) {
			case R.id.contact_option_create:
				onOptionCreateContact();
				break;
			case R.id.contact_option_search_by_name:
				onOptionSearch(IntentsTable.EXTRA_MERGE_BY_NAME);
				break;
			case R.id.contact_option_search_by_phone:
				onOptionSearch(IntentsTable.EXTRA_MERGE_BY_PHONE);
				break;
			case R.id.contact_option_search_by_email:
				onOptionSearch(IntentsTable.EXTRA_MERGE_BY_EMAIL);
				break;
			case R.id.contact_option_merge:
				onOptionMerge();
				break;
			case R.id.contact_option_delete:
				onOptionDelete();
				break;
			case R.id.contact_option_import_from_SIM:
				onOptionImportFromSim();
				break;
			case R.id.contact_option_import_from_SD:
				onOptionImportFromSD();
				break;
			case R.id.contact_option_export_to_SD:
				onOptionExportFromSD();
				break;
			case R.id.contact_option_manage_accounts:
				onOptionManageAccounts();
				break;
			case R.id.contact_option_send_vcard:
				onOptionSendVCard();
				break;
			case R.id.contact_option_settings:
				onOptionSettings();
				break;
			case R.id.contact_option_help:
				onOptionHelp();
				break;
		}
		return super.onOptionsItemSelected(item);
	}

	private void onOptionCreateContact() {
		Intent activityCall = new Intent(Intent.ACTION_INSERT);
		activityCall.setData(ContactsContract.Contacts.CONTENT_URI);
		startActivity(activityCall);
	}

	private void onOptionSearch(int searchMode) {
		Intent activityCall = new Intent(this, SearchDublicatesActivity.class);
		activityCall.putExtra(IntentsTable.EXTRA_MERGE_AUTOMATIC, searchMode);
		startActivity(activityCall);
	}

	private void onOptionMerge() {
		showDialog(R.id.dialog_merge_contacts);
	}

	private void onOptionDelete() {
		ContactsContractQueries.deleteContact(this, mContact.id);
		finish();
	}

	private void onOptionImportFromSim() {
	}

	private void onOptionImportFromSD() {
	}

	private void onOptionExportFromSD() {
	}

	private void onOptionManageAccounts() {
	}

	private void onOptionSendVCard() {
	}

	private void onOptionSettings() {
		Intent activityCall = new Intent(this, SettingsActivity.class);
		startActivity(activityCall);
	}

	private void onOptionHelp() {
		Intent activityCall = new Intent(this, HelpActivity.class);
		startActivity(activityCall);
	}

	@Override
	public void onStartRefresh() {
		showDialog(R.id.dialog_waiting);
	}

	@Override
	public void onRefreshContactsSctructure() {
		dismissDialog(R.id.dialog_waiting);
		initContact();
	}

	private void initContact() {
		long id = ContentUris.parseId(getIntent().getData());
		mContact = mContactsContractResolver.getContactById(id);
		Map<Long, Group> mapGroups = mContactsContractResolver.getMapGroups();
		mAdapter.setContact(mContact, mapGroups);
	}

	@Override
	public void onCallButtonClick(Phone phone) {
		String action = Intent.ACTION_DIAL;
		Uri uri = Uri.parse("tel:" + phone.number);
		Intent call = new Intent(action, uri);
		startActivity(call);
	}

	@Override
	public void onSmsButtonClick(Phone phone) {
		Intent call = SendMessageUtils.smsIntent(phone);
		startActivity(call);
	}

	@Override
	public void onEmailButtonClick(Email email) {
		Intent call = SendMessageUtils.emailIntent(email);
		startActivity(call);
	}

	@Override
	public void onClick(View view) {
		int viewId = view.getId();
		switch (viewId) {
			case R.id.title_bar_edit_icon:
				String action = Intent.ACTION_EDIT;
				Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, mContact.id);
				Intent intent = new Intent(action, uri);
				startActivity(intent);
				break;
		}
	}
}
